//
//  FirmwareUpgradeViewController.swift
//  EasePods
//
//  Created by 李然 on 2024/5/7.
//

import UIKit
import RxCocoa
import RxSwift
import EarbudsFunctions

class FirmwareUpgradeViewController: ViewController {
    
    let type: FirmwareSectionType

    let viewModel: FirmwareUpgradeViewModel
    
    init(type: FirmwareSectionType, viewModel: FirmwareUpgradeViewModel) {
        self.type = type
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func makeUI() {
        super.makeUI()
        
        switch type {
        case .box:
            self.navigation.item.title = R.string.localizable.setting_firmware_upgrade_earcase()
        case .ear:
            self.navigation.item.title = R.string.localizable.setting_firmware_upgrade_earbuds()
        }
        
        
        view.addSubview(topView)
        topView.snp.makeConstraints { make in
            make.top.equalTo(self.navigation.bar.snp.bottom)
            make.leading.trailing.equalToSuperview()
        }
        
        view.addSubview(iconStackView)
        iconStackView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.lessThanOrEqualTo(kScreenWidth - 40)
        }
        
        view.addSubview(button)
        button.snp.makeConstraints { make in
            make.bottom.equalTo(-kSafeBottomMargin-46)
            make.width.equalTo(kScreenWidth - 40)
            make.height.equalTo(56)
            make.centerX.equalToSuperview()
        }
        
        view.addSubview(progressView)
        progressView.snp.makeConstraints { make in
            make.leading.bottom.trailing.equalToSuperview()
            make.height.equalTo(150)
        }
    }
    
    override func bindViewModel() {
        super.bindViewModel()
        
        let input = FirmwareUpgradeViewModel.Input(buttonClick: self.button.rx.tap.asObservable())
        let output = viewModel.transform(input: input)
        
        output.state.drive(onNext: { [weak self] state in
            guard let `self` = self else {  return }
            switch state {
            case .normal:
                self.setBackEnable(true)
                self.progressView.hiddenGear {
                    self.button.isHidden = false
                    self.button.setTitle(R.string.localizable.setting_firmware_upgrade_newest_version(), for: .normal)
                    UIView.animate(withDuration: 0.28) {
                        self.button.transform = CGAffineTransform(scaleX: 1, y: 1)
                    } completion: {_ in
                    }
                }
            case .updating:
                self.setBackEnable(false)
                UIView.animate(withDuration: 0.28) {
                    self.button.transform = CGAffineTransform(scaleX: 1, y: 0.1)
                } completion: {_ in
                    self.button.isHidden = true
                    self.progressView.showGear()
                }
            case .updateSuccess:
                self.setBackEnable(true)
                self.topView.isHidden = true
                self.progressView.hiddenGear {
                    self.button.isHidden = false
                    self.button.setTitle(R.string.localizable.common_finished(), for: .normal)
                    UIView.animate(withDuration: 0.28) {
                        self.button.transform = CGAffineTransform(scaleX: 1, y: 1)
                    } completion: {_ in
                    }
                }
            case .updateFailure:
                self.setBackEnable(true)
                self.view.makeToast(R.string.localizable.setting_upgrade_failed())
            }
        }).disposed(by: rx.disposeBag)
        
        output.currentVersion
            .map { R.string.localizable.setting_firmware_current_version($0) }
            .drive(self.currentVersionLabel.rx.text)
            .disposed(by: rx.disposeBag)
        
        output.upgateProgress.drive(onNext: { [weak self] progress in
            guard let `self` = self else {  return }
            self.progressView.progress.progress = progress
            self.progressView.percentLabel.text = "\(Int(progress * 100))%"
        }).disposed(by: rx.disposeBag)
        
        output.popAction.drive(onNext: { [weak self] _ in
            guard let `self` = self else {  return }
            self.navigationController?.popViewController(animated: true)
        }).disposed(by: rx.disposeBag)
    }
    
    private func setBackEnable(_ enable: Bool) {
        self.navigation.item.leftBarButtonItem?.isEnabled = enable
        self.navigation.item.backBarButtonItem?.isEnabled = enable
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = enable
    }
    
    lazy var topView: View = {
        let view = View()
        view.backgroundColor = R.color.common_7_bg()
        view.addSubview(currentVersionLabel)
        currentVersionLabel.snp.makeConstraints { make in
            make.edges.equalTo(UIEdgeInsets(top: 12, left: 20, bottom: 12, right: 20))
        }
        return view
    }()
    
    lazy var currentVersionLabel: Label = {
        let label = Label()
        label.textColor = R.color.common_8_text()
        label.font = Fonts.systemFont(ofSize: 12)
        label.numberOfLines = 0
        label.textAlignment = .center
        return label
    }()
    
    lazy var iconImageView: ImageView = {
        let view = ImageView()
        view.image = R.image.img_firmware_update()
        view.snp.makeConstraints { make in
            make.size.equalTo(CGSize(width: 196, height: 196))
        }
        return view
    }()
    
    lazy var iconStackView: StackView = {
        let view = StackView(arrangedSubviews: [iconImageView])
        view.spacing = 36
        view.alignment = .center
        return view
    }()
    
    lazy var earUpdateTipLabel: UILabel = {
        let label = UILabel()
        label.textColor = R.color.common_3_text()
        label.font = Fonts.systemFont(ofSize: 14)
        label.numberOfLines = 0
        label.textAlignment = .center
        label.text = R.string.localizable.setting_firmware_ear_upgrade_tip()
        return label
    }()
    
    lazy var button: ScaleButton = {
        let btn = ScaleButton(type: .custom)
        btn.setTitle(R.string.localizable.setting_firmware_upgrade_newest_version(), for: .normal)
        return btn
    }()
    
    lazy var progressView: UpgradeProgressView = {
        let view = UpgradeProgressView()
        return view
    }()
}

class UpgradeProgressView: View {
    
    override func makeUI() {
        super.makeUI()
        
        self.isHidden = true
        
        backgroundColor = .clear
        
        addSubview(gearStackView)
        gearStackView.snp.makeConstraints { make in
            make.bottom.equalTo(-kSafeBottomMargin - 30)
            make.centerX.equalToSuperview()
        }
        addSubview(progress)
    }
    
    func showGear() {
        gearStackView.snp.updateConstraints { make in
            make.bottom.equalTo(-kSafeBottomMargin - 44 - 16)
        }
        UIView.animate(withDuration: 0.28) {
            self.isHidden = false
            self.layoutIfNeeded()
        }
    }
    
    func hiddenGear(complete: @escaping (() -> Void)) {
        gearStackView.snp.updateConstraints { make in
            make.bottom.equalTo(-kSafeBottomMargin - 30)
        }
        UIView.animate(withDuration: 0.28) {
            self.layoutIfNeeded()
        } completion: { _ in
            self.isHidden = true
            complete()
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        let rect = self.frame
        self.progress.frame = CGRect(x: 20, y: rect.height - 6 - kSafeBottomMargin - 44, width: rect.width - 40, height: 6)
    }
    
    lazy var gearStackView: StackView = {
        let stackView = StackView(arrangedSubviews: [gearBlackView, percentLabel])
        stackView.spacing = 3
        stackView.axis = .horizontal
        return stackView
    }()
    
    lazy var gearBlackView: RotateGearView = {
        let view = RotateGearView(image: R.image.ic_firmware_loading())
        return view
    }()
    
    lazy var progress: ProgressView = {
        let view = ProgressView()
        view.progressColor = R.color.common_22_button_n() ?? .clear
        view.backgroundColor = R.color.common_17_bg()
        view.layer.cornerRadius = 3
        return view
    }()
    
    lazy var percentLabel: Label = {
        let label = Label()
        label.textColor = R.color.common_3_text()
        label.font = Fonts.systemFont(ofSize: 12)
        label.numberOfLines = 0
        label.text = R.string.localizable.setting_firmware_upgrading()
        return label
    }()
}
